package com.csthink.mr.serial;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * 测试JDK的序列化和反序列化
 *
 * @author <a href="mailto:csthink@icloud.com">Mars</a>
 * @since 2024-04-12 17:49
 */
public class JavaSerialize {

    public static final String OUT_STUDENT_OBJ1_PATH = "out/student1.obj";
    public static final String OUT_STUDENT_OBJ2_PATH = "out/student2.obj";

    public static void main(String[] args) throws Exception {
        Student student = new Student(1, "student", 18, 190.0);
        // JDK序列化和反序列化测试代码（全字段序列化）
        serializeByJdkObject(student);
        // JDK的Data序列化机制（可以序列化指定字段）
        serializeByJdkData(student);
    }

    private static void serializeByJdkData(Student student) throws IOException {
        Path path = Paths.get(OUT_STUDENT_OBJ2_PATH);
        DataOutputStream dataOutputStream = new DataOutputStream(Files.newOutputStream(path));
        dataOutputStream.writeInt(student.getId());
        dataOutputStream.writeUTF(student.getName());
        dataOutputStream.close();

        DataInputStream dataInputStream = new DataInputStream(Files.newInputStream(path));
        int id = dataInputStream.readInt();
        String name = dataInputStream.readUTF();
        dataInputStream.close();
        System.out.println("id = " + id + ", name = " + name);
    }

    private static void serializeByJdkObject(Student jack) throws IOException, ClassNotFoundException {
        // 序列化，这种方式的序列化，实体类必须实现 Serializable
        FileOutputStream fos = new FileOutputStream(OUT_STUDENT_OBJ1_PATH);
        ObjectOutputStream outputStream = new ObjectOutputStream(fos);
        outputStream.writeObject(jack);
        outputStream.close();
        fos.close();

        // 反序列化
        FileInputStream fis = new FileInputStream(OUT_STUDENT_OBJ1_PATH);
        ObjectInputStream inputStream = new ObjectInputStream(fis);
        Student student = (Student) inputStream.readObject();
        System.out.println(student);
        fis.close();
        inputStream.close();
    }
}

class Student implements Serializable {
    private static final long serialVersionUID = 1L;

    private int id;
    private String name;
    private int age;
    private double salary;

    public Student(int id, String name, int age, double salary) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                '}';
    }
}
